using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using WorkFlowCore.BusinessDemo.Web.Data;
using WorkFlowCore.BusinessDemo.Web.Models;
using WorkFlowCore.BusinessDemo.Web.Helpers;
using Microsoft.Extensions.Primitives;
using System.Web;

namespace WorkFlowCore.BusinessDemo.Web.Controllers
{
    public class AccountController : Controller
    {
        private readonly BusinessDemoDbContext _context;
        private readonly IConfiguration _configuration;

        public AccountController(BusinessDemoDbContext context, IConfiguration configuration)
        {
            _context = context;
            _configuration = configuration;
        }

        [HttpGet]
        public IActionResult Login()
        {
            return View("Login", null);
        }

        [HttpPost]
        public async Task<IActionResult> Login(string employeeNumber, string password)
        {
            var user = _context.Users.FirstOrDefault(u =>
                u.EmployeeNumber == employeeNumber);

            if (user == null || password != "password")
            {
                ModelState.AddModelError(string.Empty, "工号或密码错误");
                return View("Login", null);
            }

            var claims = new[]
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                new Claim(ClaimTypes.Name, user.Name),
                new Claim(ClaimTypes.Email, user.Email),
                new Claim("EmployeeNumber", user.EmployeeNumber)
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
                _configuration["JwtSettings:SecretKey"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expires = DateTime.Now.AddMinutes(
                Convert.ToDouble(_configuration["JwtSettings:ExpireMinutes"]));

            var token = new JwtSecurityToken(
                issuer: _configuration["JwtSettings:Issuer"],
                audience: _configuration["JwtSettings:Audience"],
                claims: claims,
                expires: expires,
                signingCredentials: creds
            );

            var tokenString = new JwtSecurityTokenHandler().WriteToken(token);

            // Create authentication cookie
            var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
            var authProperties = new AuthenticationProperties
            {
                ExpiresUtc = expires,
                IsPersistent = true
            };

            await HttpContext.SignInAsync(
                CookieAuthenticationDefaults.AuthenticationScheme,
                new ClaimsPrincipal(claimsIdentity),
                authProperties);

            // Also set JWT token cookie for API calls
            Response.Cookies.Append("JwtToken", tokenString, new CookieOptions
            {
                HttpOnly = false, // 允许客户端JS访问
                Secure = true,
                SameSite = SameSiteMode.Strict,
                Expires = expires
            });

            // Set User Id Cookie
            Response.Cookies.Append("UserId", user.Id.ToString(), new CookieOptions
            {
                HttpOnly = false, // Allow client-side access
                Secure = true,
                SameSite = SameSiteMode.Strict,
                Expires = expires
            });

            return RedirectToAction("Index", "Home");
        }

        [Authorize]
        public async Task<IActionResult> Logout()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            Response.Cookies.Delete("JwtToken");
            return RedirectToAction("Login");
        }

        /// <summary>
        /// 验证Token
        /// 用于对接WorkFlowCore的DefaultCustomizationVerifyExtension
        /// </summary>
        /// <returns>验证结果</returns>
        [HttpGet("Account/VerifyToken")]
        [AllowAnonymous]
        public IActionResult VerifyToken()
        {
            // 从请求中获取token
            string token = GetContextParameter("authorization");
            
            if (string.IsNullOrEmpty(token))
            {
                return Ok(new VerifyOutputModel { IsValid = false });
            }
            
            // 验证token
            try
            {
                // 解析JWT token
                var handler = new JwtSecurityTokenHandler();
                var jwtToken = handler.ReadJwtToken(token.Replace("Bearer ", ""));
                
                // 获取用户信息
                var nameIdentifier = jwtToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
                var name = jwtToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
                var email = jwtToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value;
                var employeeNumber = jwtToken.Claims.FirstOrDefault(c => c.Type == "EmployeeNumber")?.Value;
                
                if (string.IsNullOrEmpty(nameIdentifier) || string.IsNullOrEmpty(name))
                {
                    return Ok(new VerifyOutputModel { IsValid = false });
                }
                
                // 获取appId参数
                string appId = GetContextParameter("appid") ?? "";
                
                // 构建验证结果
                var result = new VerifyOutputModel
                {
                    IsValid = true,
                    User = new VerifyUserModel
                    {
                        Id = employeeNumber ?? nameIdentifier,
                        Name = name,
                        IsManager = false, // 根据实际情况设置
                        AppId = appId
                    },
                    Claims = new[]
                    {
                        new VerifyClaimModel { Type = "email", Value = email ?? "" }
                    }
                };
                
                return Ok(result);
            }
            catch(Exception ex)
            {
                // 解析或验证失败，返回无效结果
                Console.WriteLine($"Token verification failed: {ex}");
                return Ok(new VerifyOutputModel { IsValid = false });
            }
        }

        /// <summary>
        /// 验证Token (POST方法)
        /// 用于对接WorkFlowCore的DefaultCustomizationVerifyExtension
        /// </summary>
        /// <returns>验证结果</returns>
        [HttpPost("Account/VerifyToken")]
        [AllowAnonymous]
        public IActionResult VerifyTokenPost()
        {
            // 调用GET方法的实现
            return VerifyToken();
        }
        
        /// <summary>
        /// 从请求中获取参数值
        /// </summary>
        /// <param name="parameterName">参数名</param>
        /// <returns>参数值</returns>
        private string GetContextParameter(string parameterName)
        {
            // 尝试从Query中获取
            var value = TryGetValue(() => Request.Query[GetRequestKey(Request.Query.Keys, parameterName)]);

            // 尝试从Form中获取
            if (string.IsNullOrWhiteSpace(value) && Request.HasFormContentType)
            {
                value = TryGetValue(() => Request.Form[GetRequestKey(Request.Form.Keys, parameterName)]);
            }
            
            // 尝试从Headers中获取
            if (string.IsNullOrWhiteSpace(value))
            {
                value = TryGetValue(() => Request.Headers[GetRequestKey(Request.Headers.Keys, parameterName)].ToString());
            }
            
            return value;
        }

        private string TryGetValue(Func<StringValues> getter)
        {
            try
            {
                var value = getter?.Invoke();
                return value.ToString();
            }
            catch
            {
                return null;
            }
        }
        
        private string GetRequestKey(IEnumerable<string> keys, string parameterName)
        {
            return keys.FirstOrDefault(key => key.Equals(parameterName, StringComparison.OrdinalIgnoreCase)) ?? string.Empty;
        }

        /// <summary>
        /// 获取默认应用程序ID，从配置文件中读取，如果未配置则使用默认值
        /// </summary>
        /// <returns>应用程序ID</returns>
        private string GetDefaultAppId()
        {
            return _configuration["WorkFlowCore:AppId"] ?? "BusinessDemo";
        }
        
        /// <summary>
        /// 显示API文档页面
        /// </summary>
        /// <returns>API文档页面</returns>
        [HttpGet("ApiDoc")]
        [AllowAnonymous]
        public IActionResult ApiDoc()
        {
            return View();
        }

        /// <summary>
        /// 自动登录演示页面
        /// </summary>
        /// <returns>自动登录演示页面</returns>
        [HttpGet("AutoLogin")]
        [Authorize]
        public IActionResult AutoLogin()
        {
            // 获取当前用户信息
            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
            var userName = User.FindFirstValue(ClaimTypes.Name);
            var employeeNumber = User.FindFirstValue("EmployeeNumber");

            // 从Cookie中获取JWT Token
            Request.Cookies.TryGetValue("JwtToken", out string token);

            if (string.IsNullOrEmpty(token))
            {
                // 如果Cookie中没有Token，尝试重新生成
                var user = _context.Users.FirstOrDefault(u => u.Id.ToString() == userId);
                if (user != null)
                {
                    var claims = new[]
                    {
                        new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                        new Claim(ClaimTypes.Name, user.Name),
                        new Claim(ClaimTypes.Email, user.Email),
                        new Claim("EmployeeNumber", user.EmployeeNumber)
                    };

                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
                        _configuration["JwtSettings:SecretKey"]));
                    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                    var expires = DateTime.Now.AddMinutes(
                        Convert.ToDouble(_configuration["JwtSettings:ExpireMinutes"]));

                    var jwtToken = new JwtSecurityToken(
                        issuer: _configuration["JwtSettings:Issuer"],
                        audience: _configuration["JwtSettings:Audience"],
                        claims: claims,
                        expires: expires,
                        signingCredentials: creds
                    );

                    token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
                }
            }

            // 构建Host项目的自动登录URL
            var hostBaseUrl = _configuration["WorkFlowCore:HostBaseUrl"] ?? "http://localhost:5173";
            var autoLoginUrl = $"{hostBaseUrl}/index.html#/login";
            
            // 默认应用ID
            var appId = GetDefaultAppId();
            
            // 构建完整的自动登录链接
            var fullAutoLoginUrl = $"{autoLoginUrl}?appid={appId}&access_token={HttpUtility.UrlEncode(token)}";

            var model = new AutoLoginViewModel
            {
                UserName = userName,
                UserId = employeeNumber ?? userId,
                Token = token,
                AutoLoginUrl = autoLoginUrl,
                FullAutoLoginUrl = fullAutoLoginUrl,
                HostBaseUrl = hostBaseUrl,
                AppId = appId ?? GetDefaultAppId()
            };

            return View(model);
        }

        /// <summary>
        /// 自动登录演示页面（POST方法，用于更新HostBaseUrl和AppId）
        /// </summary>
        /// <returns>自动登录演示页面</returns>
        [HttpPost("AutoLogin")]
        [Authorize]
        public IActionResult AutoLogin(string hostBaseUrl, string appId)
        {
            // 获取当前用户信息
            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
            var userName = User.FindFirstValue(ClaimTypes.Name);
            var employeeNumber = User.FindFirstValue("EmployeeNumber");

            // 从Cookie中获取JWT Token
            Request.Cookies.TryGetValue("JwtToken", out string token);

            if (string.IsNullOrEmpty(token))
            {
                // 如果Cookie中没有Token，尝试重新生成
                var user = _context.Users.FirstOrDefault(u => u.Id.ToString() == userId);
                if (user != null)
                {
                    var claims = new[]
                    {
                        new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                        new Claim(ClaimTypes.Name, user.Name),
                        new Claim(ClaimTypes.Email, user.Email),
                        new Claim("EmployeeNumber", user.EmployeeNumber)
                    };

                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
                        _configuration["JwtSettings:SecretKey"]));
                    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                    var expires = DateTime.Now.AddMinutes(
                        Convert.ToDouble(_configuration["JwtSettings:ExpireMinutes"]));

                    var jwtToken = new JwtSecurityToken(
                        issuer: _configuration["JwtSettings:Issuer"],
                        audience: _configuration["JwtSettings:Audience"],
                        claims: claims,
                        expires: expires,
                        signingCredentials: creds
                    );

                    token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
                }
            }

            // 使用用户提供的hostBaseUrl，如果为空则使用配置文件中的值
            if (string.IsNullOrEmpty(hostBaseUrl))
            {
                hostBaseUrl = _configuration["WorkFlowCore:HostBaseUrl"] ?? "http://localhost:5000";
            }
            
            // 使用用户提供的appId，如果为空则使用默认值
            if (string.IsNullOrEmpty(appId))
            {
                appId = GetDefaultAppId();
            }
            
            var autoLoginUrl = $"{hostBaseUrl}/index.html#/login";
            
            
            // 构建完整的自动登录链接
            var fullAutoLoginUrl = $"{autoLoginUrl}?appid={appId}&access_token={HttpUtility.UrlEncode(token)}";
            

            var model = new AutoLoginViewModel
            {
                UserName = userName,
                UserId = employeeNumber ?? userId,
                Token = token,
                AutoLoginUrl = autoLoginUrl,
                FullAutoLoginUrl = fullAutoLoginUrl,
                HostBaseUrl = hostBaseUrl,
                AppId = appId ?? GetDefaultAppId()
            };

            return View(model);
        }
    }
}
